using UnityEngine;

public class TankTower : MonoBehaviour
{
	public float maxVertivalDownAngel = 10f;

	public float maxVertivalUpAngel = 30f;

	public float towerRotationSpeed = 2f;

	private float currentRotationSpeed = 1f;

	private CarBehavior car;

	public Transform cannon;

	[HideInInspector]
	public Quaternion newCannonRotation = Quaternion.identity;

	[HideInInspector]
	public Quaternion newTowerRotation = Quaternion.identity;

	private Transform _towerAimPivot;

	private Transform _cannonAimPivot;

	private Transform _towerRot;

	private float tankAngelLerp;

	private Quaternion lastTowerRot;

	private Quaternion towerRotation;

	private float currentTowerRotationSpeed;

	private Vector3 lastTankForward;

	private float lastCamAngle;

	private Vector3 lastTowerRotForward = Vector3.zero;

	private Transform towerAimPivot
	{
		get
		{
			if (_towerAimPivot == null)
			{
				_towerAimPivot = new GameObject("Tower_Aim_Pivot").transform;
				_towerAimPivot.SetParent(base.transform);
				_towerAimPivot.localPosition = Vector3.zero;
				_towerAimPivot.localRotation = Quaternion.identity;
				_towerAimPivot.SetParent(base.transform.parent);
			}
			return _towerAimPivot;
		}
	}

	private Transform cannonAimPivot
	{
		get
		{
			if (_cannonAimPivot == null)
			{
				_cannonAimPivot = new GameObject("Cannon_Aim_Pivot").transform;
				_cannonAimPivot.SetParent(cannon);
				_cannonAimPivot.localPosition = Vector3.zero;
				_cannonAimPivot.localRotation = Quaternion.identity;
				_cannonAimPivot.SetParent(cannon.parent);
			}
			return _cannonAimPivot;
		}
	}

	private Transform towerRot
	{
		get
		{
			if (_towerRot == null)
			{
				_towerRot = new GameObject("Tower_Rot").transform;
				_towerRot.SetParent(base.transform);
				_towerRot.localPosition = Vector3.zero;
				_towerRot.localRotation = Quaternion.identity;
				_towerRot.SetParent(base.transform.parent);
			}
			return _towerRot;
		}
	}

	private void Start()
	{
		car = GetComponentInParent<CarBehavior>();
	}

	public void OnUpdate()
	{
		if ((bool)GameController.instance && (bool)GameController.instance.playerScript && !(car == null) && !car.isFree && !(GameController.instance.playerScript.currentCar == null) && GameController.instance.playerScript.currentCar == car)
		{
			ColcitateTowerRotation();
			ApplyTowerRotation();
		}
	}

	public void Subscribe()
	{
		TPSCamera.AfterLateUpdate += OnUpdate;
	}

	public void UnSubscribe()
	{
		TPSCamera.AfterLateUpdate -= OnUpdate;
	}

	private void OnDestroy()
	{
		UnSubscribe();
	}

	private void Update()
	{
		if ((bool)GameController.instance && (bool)GameController.instance.playerScript && !(car == null) && !car.isFree && GameController.instance.playerScript.currentCar != car)
		{
			currentRotationSpeed = 10f;
			base.transform.localRotation = Quaternion.Lerp(base.transform.localRotation, newTowerRotation, Time.deltaTime * currentRotationSpeed);
			cannon.transform.localRotation = Quaternion.Lerp(cannon.transform.localRotation, newCannonRotation, Time.deltaTime * currentRotationSpeed);
		}
	}

	private void ColcitateTowerRotation()
	{
		Vector3 cameraHitPoint = TPSCamera.instance.cameraHitPoint;
		towerAimPivot.transform.LookAt(cameraHitPoint);
		cannonAimPivot.transform.LookAt(cameraHitPoint);
		float num = SignedAngle(towerRot.parent.forward, lastTankForward, towerRot.parent.up);
		lastTankForward = towerRot.parent.forward;
		if (towerRotationSpeed * Time.deltaTime > Mathf.Abs(num))
		{
			currentTowerRotationSpeed = towerRotationSpeed * Time.deltaTime;
		}
		else
		{
			currentTowerRotationSpeed = Mathf.Abs(num);
		}
		float num2 = Mathf.Sign(SignedAngle(towerAimPivot.forward, towerRot.forward, towerRot.up));
		if (Mathf.Abs(towerRot.localRotation.eulerAngles.y - towerAimPivot.localRotation.eulerAngles.y) > currentTowerRotationSpeed)
		{
			float num3 = towerRot.localRotation.eulerAngles.y + currentTowerRotationSpeed * num2;
			if (num3 > 180f)
			{
				num3 -= 360f;
			}
			newTowerRotation = Quaternion.Euler(0f, num3, 0f);
			towerRot.localRotation = newTowerRotation;
		}
		else
		{
			towerRot.localRotation = Quaternion.Euler(0f, towerAimPivot.localRotation.eulerAngles.y, 0f);
		}
		float num4 = Mathf.Sign(SignedAngle(towerAimPivot.forward, lastTowerRotForward, towerRot.up));
		tankAngelLerp = Mathf.Lerp(tankAngelLerp, num, Time.deltaTime * 5f);
		if (Mathf.Abs(tankAngelLerp) > towerRotationSpeed * Time.deltaTime * 0.5f && Mathf.Sign(tankAngelLerp) != num4 && Vector3.Angle(towerAimPivot.forward, towerRot.forward) > 1.5f)
		{
			towerRot.rotation = Quaternion.Euler(towerRot.rotation.eulerAngles.x, lastTowerRot.eulerAngles.y, towerRot.rotation.eulerAngles.z);
		}
		else
		{
			lastTowerRot = towerRot.rotation;
		}
		lastTowerRotForward = towerRot.forward;
		if (TPSCamera.instance.cameraHitTag.Equals("MyVehicle"))
		{
			return;
		}
		if (Mathf.Abs(newCannonRotation.eulerAngles.x - cannonAimPivot.localRotation.eulerAngles.x) > towerRotationSpeed * Time.deltaTime)
		{
			float num5 = newCannonRotation.eulerAngles.x + towerRotationSpeed * Time.deltaTime * 0.5f * Mathf.Sign(SignedAngle(cannonAimPivot.forward, cannon.forward, cannon.right));
			if (num5 > 180f)
			{
				num5 -= 360f;
			}
			num5 = Mathf.Clamp(num5, 0f - maxVertivalUpAngel, maxVertivalDownAngel);
			newCannonRotation = Quaternion.Euler(num5, 0f, 0f);
		}
		else
		{
			newCannonRotation = Quaternion.Euler(cannonAimPivot.localRotation.eulerAngles.x, 0f, 0f);
		}
	}

	private void ApplyTowerRotation()
	{
		base.transform.localRotation = towerRot.localRotation;
		cannon.transform.localRotation = newCannonRotation;
	}

	public static float SignedAngle(Vector3 a, Vector3 b, Vector3 normal)
	{
		Vector3 lhs = Vector3.Cross(normal, a);
		float num = Vector3.Angle(a, b);
		float num2 = num * Mathf.Sign(Vector3.Dot(lhs, b));
		return 0f - num2;
	}

	public void Reset()
	{
		towerRot.localRotation = Quaternion.identity;
		base.transform.localRotation = Quaternion.identity;
		cannon.localRotation = Quaternion.identity;
		towerAimPivot.localRotation = Quaternion.identity;
		cannonAimPivot.localRotation = Quaternion.identity;
		newTowerRotation = towerRot.localRotation;
		newCannonRotation = towerRot.localRotation;
		tankAngelLerp = 0f;
		lastTowerRot = towerRot.localRotation;
		towerRotation = towerRot.localRotation;
		currentTowerRotationSpeed = 0f;
		lastTankForward = base.transform.forward;
		lastCamAngle = 0f;
		lastTowerRotForward = base.transform.forward;
	}
}
